package com.chat.room.service;

import com.chat.room.bean.ChatUserInfo;
import com.chat.room.common.CommonConstant;
import com.chat.room.common.ServiceConstant;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;

import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;

@Data
@Slf4j
public class ChatRoomServerListener {

    /*启动服务监听*/
    public void listener() throws IOException {
        log.info("开始启用服务器聊天监听");
        ServerSocket serverSocket = new ServerSocket(CommonConstant.SERVICE_TRANS_PORT);
        while (true) {
            /*如果有服务接入，则进行接入处理*/
            Socket accept = serverSocket.accept();
            ChatUserInfo chatUserInfo = new ChatUserInfo(accept.getInetAddress().getHostName(), accept.getInetAddress(), accept.getPort(), accept);
            addUserInfo(chatUserInfo);
            /*加入线程队列，启动用户管理*/
            ServiceConstant.THREAD_POOL_EXECUTOR.execute(new ReceiveMessage(chatUserInfo));
        }
    }

    /**
     * 新用户接入
     *
     * @param chatUserInfo
     */
    private void addUserInfo(ChatUserInfo chatUserInfo) {

        if (null != chatUserInfo && !ServiceConstant.CHAT_USER_INFO_LIST.contains(chatUserInfo)) {
            log.info("新用户{}:{}接入", chatUserInfo.getNickName(), chatUserInfo.getPort());
            ServiceConstant.CHAT_USER_INFO_LIST.add(chatUserInfo);
            sendMsgToAllInfo("欢迎用户[" + chatUserInfo.getNickName() + "]加入聊天室", null);
        }
    }

    public void sendMsgToAllInfo(String message, ChatUserInfo unSendChatUserInfo) {
        for (ChatUserInfo userInfo : ServiceConstant.CHAT_USER_INFO_LIST) {
            if (null != unSendChatUserInfo && userInfo.equals(unSendChatUserInfo)) {
                /*如果是当前用户自己，则不进行发送*/
                continue;
            }
            sendMsg(userInfo, message);
        }
    }

    /*进行单用户消息发送*/
    public void sendMsg(ChatUserInfo chatUserInfo, String message) {
        chatUserInfo.getPrintStream().println(message);
    }

    /**
     * 消息接收处理类
     */
    @Data
    private class ReceiveMessage implements Runnable {

        private ChatUserInfo chatUserInfo;

        private boolean flag = true;

        public ReceiveMessage(ChatUserInfo chatUserInfo) {
            this.chatUserInfo = chatUserInfo;
        }

        @Override
        public void run() {
            reply();
            while (flag) {
                String message = null;
                try {
                    message = chatUserInfo.getBufferReader().readLine();
                } catch (IOException e) {
                    log.error("获取消息异常：{}", message);
                    message = null;
                }
                log.info("服务端接收到客户端{}发送过来的消息：{}", chatUserInfo.getNickName(), message);
                if (message == null || CommonConstant.BYEBYE.equals(message)) {
                    log.info("用户{}:{}退出聊天", chatUserInfo.getNickName(), chatUserInfo.getPort());
                    close();
                    continue;
                }
                    /*进行消息广播，发给除自己以外的所有客户端*/
                sendMsgToAllInfo(chatUserInfo.getNickName() + ":" + chatUserInfo.getPort() + ":" + message, chatUserInfo);
            }
        }

        private void reply() {
            sendMsg(chatUserInfo, "欢迎加入聊天室，你现在可以发言了!");
        }

        /**
         * 关闭聊天
         */
        public void close() {
            this.flag = false;
            try {
                chatUserInfo.getAccept().close();
            } catch (IOException e) {
                log.error("关闭socket异常：{}", e);
            } finally {
                ServiceConstant.CHAT_USER_INFO_LIST.remove(chatUserInfo);
                sendMsgToAllInfo("用户[" + chatUserInfo.getNickName() + ":" + chatUserInfo.getPort() + "]退出聊天，当前在线人数：" + ServiceConstant.CHAT_USER_INFO_LIST.size(), null);
            }

        }
    }

}